# -*- conding:UTF-8 -*-

'''
@ Project: P8 hw register_login
@ File: users.py
@ Author: 罗婷
@ Date：2022/6/16 16:57

'''
import random
import string
from io import BytesIO
import redis
from captcha.image import ImageCaptcha
from flask import Blueprint, jsonify, make_response, Response
from flask_restful import Api, Resource, reqparse, marshal
from werkzeug.security import generate_password_hash, check_password_hash
from common.celery.tasks import send_smscode
from common.jwt.check_token import token_check
from common.jwt.token_generate import generate_token
from common.model_fields.users import users_fields
from common.models import db
from common.models.users import Users

user_bp = Blueprint('user_bp', __name__, url_prefix='/user')
api = Api(user_bp)


# 发送短信验证码
class SendSms(Resource):
    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('phone')
        args = parser.parse_args()
        phone = args['phone']

        sms_code = f'{random.randint(10000, 99999)}'
        ret = send_smscode.delay(phone, sms_code)
        key = f'phone:{phone}'
        print(f'发送短信:{sms_code}')
        if ret:  # 发送成功  存入redis
            rds = redis.Redis()
            rds.set(key, sms_code, ex=3*60*60)
            return jsonify(message='短信发送成功', code=200)
        else:
            return jsonify(message='短信发送失败', code=400)


# 注册
class Register(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        argss = ['username', 'password', 'code', 'phone', 'password2']
        for i in argss:
            parser.add_argument(i)
        args = parser.parse_args()
        account = args['username']
        password = args['password']
        sms_code_ = args['code']
        phone = args['phone']
        password2 = args['password2']
        if not all([account, password, sms_code_, phone, password2]):
            return jsonify(message='请完善注册信息', code=400)

        if password != password2:
            return jsonify(message='两次密码输入不一致', code=400)
        key = f'phone:{phone}'
        rds = redis.Redis()
        sms_code =rds.get(key)
        if sms_code.decode() != sms_code_:
            return jsonify(message='验证码不正确', code=400)
        pwd = generate_password_hash(password)
        try:
            user = Users(account=account, password=pwd, phone=phone)
            db.session.add(user)
            db.session.commit()
        except Exception as e:
            print(f'添加用户失败{e}')
            return jsonify(message='注册用户失败', code=500)
        return jsonify(message='注册用户成功', code=200)




# 使用封装的方法生成图片验证码
# # 生成图片验证码
class ImgCode(Resource):
    # def get(self):
    #     parser = reqparse.RequestParser()
    #     parser.add_argument('uuid')
    #     args = parser.parse_args()
    #     uuid = args['uuid']
    #     # text图片验证码 , image
    #     text, image = Captcha.gene_graph_captcha()
    #     if uuid:  # 接收到uuid
    #         rds = redis.Redis()
    #         rds.set(uuid, text, ex=3*60*60)
    #         file = BytesIO()
    #         image.save(file, 'png')
    #         file.seek(0)
    #         resp = make_response(file.read())
    #         resp.content_type = 'image/png'
    #         return resp

    def get(self):
        # 不封装
        parser = reqparse.RequestParser()
        parser.add_argument('uuid')
        args = parser.parse_args()
        uuid = args['uuid']
        # text图片验证码  image图片
        text = ''.join(random.sample(string.digits + string.ascii_lowercase, 5))  # 生成验证码
        print('图片验证码', text)
        captcha = ImageCaptcha()  # 生成图片
        img = captcha.generate(text)   # 验证码放图片上
        if uuid:  # 接收到uuid  存入redis
            rds = redis.Redis()
            rds.set(uuid, text, ex=3*60*60)
            return Response(img)



class Login(Resource):
    """
    接收数据 校验密码 图片验证码  生成token 返回数据
    """
    def post(self):
        parser = reqparse.RequestParser()
        argss = ['account', 'password', 'img_code', 'uuid']
        for i in argss:
            parser.add_argument(i)
        args = parser.parse_args()
        account = args['account']
        password = args['password']
        img_code_ = args['img_code']
        uuid = args['uuid']

        print(f'接收到的数据account:{account}, password:{password},img_code_:{img_code_}, uuid:{uuid} ')
        if not all([account, password, img_code_, uuid]):
            return jsonify(message='请完善登录信息', code=400)

        # 校验图片验证码
        rds = redis.Redis()
        img_code = rds.get(uuid)
        if img_code.decode() != img_code_:
            return jsonify(message='图片验证码错误', code=400)

        # 校验密码
        user = Users.query.filter_by(account=account).first()
        print('user@@@@@@@@', user)
        d_password = user.password
        ret = check_password_hash(d_password, password)
        if ret:
            # 生成token
            payload = {'uid': user.uid, 'account': account}
            token = generate_token(payload)
            if token:
                # 需要的数据
                data = {
                    'token': token,
                    'account': account,
                    'uid': user.uid,
                }
                return jsonify(message='登录成功', code=200, data=data)
            else:
                return jsonify(message='token生成失败', code=400)
        else:
            return jsonify(message='密码错误', code=400)


# 获取用户信息
#
class UserInfo(Resource):
    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('token')
        args = parser.parse_args()
        token = args['token']
        # print('获取用户信息 参数^^^^^^^^', 'token', token)
        payload = token_check(token)
        user_id = payload['uid']
        # print('获取用户信息 user_id^^^^^^^^', user_id)
        user = Users.query.filter_by(uid=user_id).first()
        user_data = marshal(user, users_fields)
        # print('用户信息获取成功', user_data)
        return jsonify(message='用户信息获取成功', code=200, data=user_data)


# 注册
api.add_resource(Register, '/register_user')
# 发送短信验证码
api.add_resource(SendSms, '/phone_code')
# 登录
api.add_resource(Login, '/login')
# 图片验证码
api.add_resource(ImgCode, '/code')
# 获取用户信息
api.add_resource(UserInfo, '/user_info')